﻿using HtmlAgilityPack;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using XjjXmm.FrameWork.Cache;
using XjjXmm.FrameWork.ToolKit;
using XjjXmm.Spider.biquge;

namespace XjjXmm.Spider.spider.GebiquCom;

internal class GebiquComSpider : ISiteSpider
{
    //https://www.zhihu.com/question/359676590/answer/1615531107

    //private readonly HttpClient _client;
    //private readonly ISqlSugarClient _sqlSugarClient;
    // private readonly ILogger<NovelSpider> _logger;

    private readonly ClientBuildHelper<GebiquComSpider> buildHelper;

    private HttpClient _client => buildHelper.Client;

    public GebiquComSpider(ClientBuildHelper<GebiquComSpider> buildHelper)
    {
        buildHelper.Build();
        this.buildHelper = buildHelper;
    }

    public string Domain => GetSetting().Domain;

    public SiteSetting? GetSetting()
    {
        return Setting.FindSetting<GebiquComSpider>();
    }

    public ILogger GetLogger()
    {
        return Log.ForContext<GebiquComSpider>();
    }


    public async IAsyncEnumerable<string> FetchNovelLinks()
    {
        //玄幻小说
        await foreach (var link in GetNovelLink("xuanhuanmofa"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("xiuzhenxiaoshuo"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("dushixiaoshuo"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("lishijunshi"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("youxixiaoshuo"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("kehuanlingyi"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("tongrenxiaoshuo"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("nvshengyanqing"))
        {
            yield return link;
        }

        await foreach (var link in GetNovelLink("zonghexiaoshuo"))
        {
            yield return link;
        }
    }

    protected async IAsyncEnumerable<string> GetNovelLink(string category)
    {
        int page = 1;
        while (true)
        {
            var xuanhuanDiectory = await _client.GetStringAsync($"{category}/{page}.html");
            var xuanhuanHtmlDoc = new HtmlDocument();
            xuanhuanHtmlDoc.LoadHtml(xuanhuanDiectory);

            var nodes = xuanhuanHtmlDoc.DocumentNode.SelectNodes("//div[@id='newscontent']/div[@class='l']/ul/li");
            foreach (var node in nodes)
            {
                var zuopns = node.SelectSingleNode(".//span[@class='s2']/a");

                //Logger.Debug($"主题:{subjectNode.InnerText}");

                if (zuopns == null)
                {
                    continue;
                }


                var href = zuopns.Attributes["href"].Value;
                var text = zuopns.InnerText;

                //Logger.Debug($"{text}:{href}");

                yield return href;

                //var temp = await RedisClient.Instance.ListRightPush(keyArticle, href);
            }

            var totals = xuanhuanHtmlDoc.DocumentNode.SelectSingleNode("//em[@id='pagestats']").InnerText.Split('/').Last().Trim();

            await Task.Delay(5000);

            if (totals == page.ToString())
            {
                yield break;
            }



            page++;

        }
    }

    public async Task<NovelModel> FetchNovel(string url)
    {
        await Task.Delay(8000);
        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        var main = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='info']");
        var title = main.SelectSingleNode(".//h1").InnerText;
        var author = main.SelectSingleNode(".//p").InnerText.Replace("&nbsp;", "").Replace("作者：", "");
        var updateTime = main.SelectSingleNode(".//p[3]").InnerText.Replace("最后更新：", "").Trim().ToDateTime();
        var lastChapter = "";// main.SelectSingleNode(".//p[4]/a").InnerText.Trim();

        var category = main.SelectSingleNode("//div[@class='con_top']/a[2]").InnerText.Trim();

        var isInstalment = main.SelectSingleNode("//div[@id='fmimg']/span[@class='b']") != null;

        var intro = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='intro']").InnerHtml;

        var novel = new NovelModel()
        {
            Title = title,
            Author = author,
            Category = category,
            UpdateTime = updateTime,
            LastChapter = lastChapter,
            IsInstalment = isInstalment,
            Intro = intro
        };

        return novel;
    }

    public async Task<string> FetchContent(string url)
    {
        await Task.Delay(5000);

        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        //*[@id="wrapper"]/div[4]/div/div[2]/h1
        var title = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='content_read']//div[@class='bookname']/h1").InnerText.Trim();
        var content = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='content']").InnerHtml;
        //*[@id="content"]

        return content;
    }




    /// <summary>
    /// 某一个小说的所有章节
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    public async IAsyncEnumerable<Chapter> FetchChapters(string url)
    {
        GetLogger().Information(Domain + ": 开始抓取章节列表：" + url);


        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);


        var paras = htmlDoc.DocumentNode.SelectNodes("//div[@id='list']/dl/dt[2]/following-sibling::dd"); //*[@id="list"]/dl/dd[1]/a
        foreach (var item in paras)
        {
            var link = item.SelectSingleNode(".//a");

            var href = link.Attributes["href"].Value;
            var text = link.InnerText;

            yield return new Chapter
            {
                Title = text,
                Link = href
            };
            //yield return new
            //{
            //    title = title,
            //    author = author,
            //    chapter = text,
            //    href = href
            //};
            // await RedisClient.Instance.ListRightPush(key, href);

            // await RedisClient.Instance.HashSet(key, text + "_href", href);
            // _logger.LogDebug($"{text}:{href}");
        }
        //*[@id="info"]
    }




}
